#include <dim-sum/printk.h>
#include <dim-sum/sched.h>
#include <dim-sum/string.h>
#include <dim-sum/syscall.h>

#include <kapi/dim-sum/task.h>

/**
 * 根据POSIX定义，孤立的进程组不受终端终止信号影响
 * 但是受到SIGHUP和SIGCONT信号的影响
 */
int is_orphaned_pg(int pgrp)
{
	return 0;
}

int capable(int cap)
{
	return 1;
}

int in_group_p(gid_t grp)
{
	return 1;
}

struct task_desc *create_process(struct task_desc* parent, int (*func)(void *data),
			void *data,
			char *name,
			int prio,
			int sched_policy,
			char * const *argv,
			char * const *envp)
{
	struct	task_create_param param;
	struct task_desc *ret = NULL;
	int len;
	void* t_func = func;

	if (!name) {
		pr_err("Create task error: name is NULL\n");
		return ret;
	}

	if (prio < 0 || prio >= MAX_RT_PRIO) {
		pr_err("Create task error: prio is error\n");
		return ret;
	}
	
	param.app_flags = !t_func ? TASK_TY_USER : TASK_TY_KERN;
	len = strlen(name);
	if (len >= sizeof(param.name))
		len = sizeof(param.name) - 1;
	strncpy(param.name, name, len);
	param.name[len] = 0;
	param.parent = parent;
	param.argv = argv;
	param.envp = envp;
	param.prio  = prio;
	param.sched_policy  = sched_policy;
	param.func = t_func;
	param.data = data;
	ret = create_task(&param);

	WARN_ON(!ret, "create task [%s] error\n", param.name);
	return ret;
}

TaskId old_create_process(int (*func)(void *data),
			void *data,
			char *name,
			int prio,
			int sched_policy)
{
	struct task_desc* t;
	t = create_process(current, func, data, name, prio, sched_policy, NULL, NULL);
	BUG_ON(!t);
	return (TaskId)(t->pid);
}

struct task_desc *kapp_create_process(
			char *name,
			int prio,
			int sched_policy,
			char * const *argv,
			char * const *envp)
{
	return create_process(current, NULL, NULL, 
						name, prio, sched_policy, argv, envp);
}

struct task_desc *kthread_create(int (*threadfn)(void *data),
				   void *data,
				   int prio,
				   const char namefmt[],
				   ...)
{
	char name[TASK_NAME_LEN];
	struct task_desc *task;
	va_list args;

	va_start(args, namefmt);
	vsnprintf(name, TASK_NAME_LEN, namefmt, args);
	va_end(args);

	task = (struct task_desc *)create_process(current, threadfn,
			data, name, prio, SCHED_FIFO, NULL, NULL);

	return task;
}

asmlinkage long sys_getpid(void)
{
	return current->pid;
}


asmlinkage pid_t sys_getppid(void)
{
	return current->pid;
}


asmlinkage long sys_getuid(void)
{
	return current->uid;
}

asmlinkage uid_t sys_geteuid(void)
{
	return current->euid;
}

asmlinkage gid_t sys_getgid(void)
{
	return current->gid;
}

asmlinkage gid_t sys_getegid(void)
{
	return current->egid;
}

asmlinkage long sys_gettid(void)
{
	return current->pid;
}
